#include "wxschoicebook.h"
#include "../../wxsadvqppchild.h"
#include "../wxsitemresdata.h"
#include <wx/choicebk.h>
#include <prep.h>
#include <wx/sizer.h>
#include <wx/textctrl.h>
#include <wx/checkbox.h>
#include <wx/panel.h>
#include <wx/intl.h>
#include <wx/string.h>

namespace {
  wxsRegisterItem<wxsChoicebook> Reg( _T( "Choicebook" ), _T( "单选列表框" ), wxsTContainer, _T( "标准" ), 300 );
  class wxsChoicebookExtra: public wxsPropertyContainer {
    public:
      wxsChoicebookExtra():
        m_Label( _T( "Page name" ) ),
        m_Selected( false ) {}
      wxString m_Label;
      bool m_Selected;
    protected:
      virtual void OnEnumProperties( M_Code_unused long Flags ) {
        WXS_SHORT_STRING( wxsChoicebookExtra, m_Label, _T( "页面名称" ), _T( "label" ), _T( "" ), false );
        WXS_BOOL( wxsChoicebookExtra, m_Selected, _T( "选定的页" ), _T( "selected" ), false );
      }
  };

  class wxsChoicebookParentQP: public wxsAdvQPPChild {
    public:
      wxsChoicebookParentQP( wxsAdvQPP* parent, wxsChoicebookExtra* Extra, wxWindowID id = -1 ):
        wxsAdvQPPChild( parent, _T( "Choicebook" ) ),
        m_Extra( Extra ) {
        wxStaticBoxSizer* StaticBoxSizer2;
        wxStaticBoxSizer* StaticBoxSizer1;
        wxFlexGridSizer* FlexGridSizer1;
        Create( parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T( "id" ) );
        FlexGridSizer1 = new wxFlexGridSizer( 0, 1, 0, 0 );
        StaticBoxSizer1 = new wxStaticBoxSizer( wxVERTICAL, this, _T( "Label" ) );
        Label = new wxTextCtrl( this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T( "ID_TEXTCTRL1" ) );
        StaticBoxSizer1->Add( Label, 0, wxEXPAND, 5 );
        FlexGridSizer1->Add( StaticBoxSizer1, 1, wxEXPAND, 5 );
        StaticBoxSizer2 = new wxStaticBoxSizer( wxHORIZONTAL, this, _T( "Selection" ) );
        Selected = new wxCheckBox( this, ID_CHECKBOX1, _T( "Selected" ), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T( "ID_CHECKBOX1" ) );
        Selected->SetValue( false );
        StaticBoxSizer2->Add( Selected, 1, wxEXPAND, 5 );
        FlexGridSizer1->Add( StaticBoxSizer2, 1, wxEXPAND, 5 );
        SetSizer( FlexGridSizer1 );
        FlexGridSizer1->Fit( this );
        FlexGridSizer1->SetSizeHints( this );
        Connect( ID_TEXTCTRL1, wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( wxsChoicebookParentQP::OnLabelText ) );
        Connect( ID_CHECKBOX1, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( wxsChoicebookParentQP::OnSelectionChange ) );
        ReadData();
        Label->Connect( -1, wxEVT_KILL_FOCUS, ( wxObjectEventFunction )&wxsChoicebookParentQP::OnLabelKillFocus, 0, this );
      }

      virtual ~wxsChoicebookParentQP() {
      }

    private:

      virtual void Update() {
        ReadData();
      }

      void ReadData() {
        if( !GetPropertyContainer() || !m_Extra ) {
          return;
        }
        Label->SetValue( m_Extra->m_Label );
        Selected->SetValue( m_Extra->m_Selected );
      }

      void SaveData() {
        if( !GetPropertyContainer() || !m_Extra ) {
          return;
        }
        m_Extra->m_Label = Label->GetValue();
        m_Extra->m_Selected = Selected->GetValue();
        NotifyChange();
      }
      static const long ID_TEXTCTRL1;
      static const long ID_CHECKBOX1;
      void OnLabelText( wxCommandEvent& event );
      void OnLabelKillFocus( wxFocusEvent& event );
      void OnSelectionChange( wxCommandEvent& event );
      wxCheckBox* Selected;
      wxTextCtrl* Label;
      wxsChoicebookExtra* m_Extra;
      DECLARE_EVENT_TABLE()
  };
  const long wxsChoicebookParentQP::ID_TEXTCTRL1 = wxNewId();
  const long wxsChoicebookParentQP::ID_CHECKBOX1 = wxNewId();
  BEGIN_EVENT_TABLE( wxsChoicebookParentQP, wxPanel )
  END_EVENT_TABLE()
  void wxsChoicebookParentQP::OnLabelText( M_Code_unused wxCommandEvent& event ) { SaveData(); }
  void wxsChoicebookParentQP::OnLabelKillFocus( M_Code_unused wxFocusEvent& event ) { SaveData(); event.Skip(); }
  void wxsChoicebookParentQP::OnSelectionChange( M_Code_unused wxCommandEvent& event ) { SaveData(); }
  WXS_ST_BEGIN( wxsChoicebookStyles, _T( "" ) )
  WXS_ST_CATEGORY( "wxChoicebook" )
  WXS_ST( wxCHB_DEFAULT )
  WXS_ST( wxCHB_LEFT )
  WXS_ST( wxCHB_RIGHT )
  WXS_ST( wxCHB_TOP )
  WXS_ST( wxCHB_BOTTOM )
  WXS_ST_DEFAULTS()
  WXS_ST_END()
  WXS_EV_BEGIN( wxsChoicebookEvents )
  WXS_EVI( EVT_CHOICEBOOK_PAGE_CHANGED, wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED, wxChoicebookEvent, PageChanged )
  WXS_EVI( EVT_CHOICEBOOK_PAGE_CHANGING, wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING, wxChoicebookEvent, PageChanging )
  WXS_EV_END()

}

wxsChoicebook::wxsChoicebook( wxsItemResData* Data ):
  wxsContainer( Data, &Reg.Info, wxsChoicebookEvents, wxsChoicebookStyles ), m_CurrentSelection( 0 ) {
}

void wxsChoicebook::OnEnumContainerProperties( M_Code_unused long Flags ) {
}

bool wxsChoicebook::OnCanAddChild( wxsItem* Item, bool ShowMessage ) {
  if( Item->GetType() == wxsTSizer ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "无法将sizer添加到Choicebook.\nAdd panels first" ) );
    }
    return false;
  }
  return wxsContainer::OnCanAddChild( Item, ShowMessage );
}

wxsPropertyContainer* wxsChoicebook::OnBuildExtra() {
  return new wxsChoicebookExtra();
}

wxString wxsChoicebook::OnXmlGetExtraObjectClass() {
  return _T( "choicebookpage" );
}

void wxsChoicebook::OnAddChildQPP( wxsItem* Child, wxsAdvQPP* QPP ) {
  wxsChoicebookExtra* CBExtra = ( wxsChoicebookExtra* )GetChildExtra( GetChildIndex( Child ) );
  if( CBExtra ) {
    QPP->Register( new wxsChoicebookParentQP( QPP, CBExtra ), _T( "Choicebook" ) );
  }
}

wxObject* wxsChoicebook::OnBuildPreview( wxWindow* Parent, long PreviewFlags ) {
  UpdateCurrentSelection();
  wxChoicebook* Choicebook = new wxChoicebook( Parent, -1, Pos( Parent ), Size( Parent ), Style() );
  if( !GetChildCount() && !( PreviewFlags & pfExact ) ) {
    Choicebook->AddPage(
      new wxPanel( Choicebook, -1, wxDefaultPosition, wxSize( 50, 50 ) ),
      _T( "No pages" ) );
  }
  AddChildrenPreview( Choicebook, PreviewFlags );
  for( int i = 0; i < GetChildCount(); i++ ) {
    wxsItem* Child = GetChild( i );
    wxsChoicebookExtra* CBExtra = ( wxsChoicebookExtra* )GetChildExtra( i );
    wxWindow* ChildPreview = wxDynamicCast( GetChild( i )->GetLastPreview(), wxWindow );
    if( !ChildPreview ) {
      continue;
    }
    bool Selected = ( Child == m_CurrentSelection );
    if( PreviewFlags & pfExact ) {
      Selected = CBExtra->m_Selected;
    }
    Choicebook->AddPage( ChildPreview, CBExtra->m_Label, Selected );
  }
  return Choicebook;
}

void wxsChoicebook::OnBuildCreatingCode() {
  switch( GetLanguage() ) {
  case wxsCPP: {
    AddHeader( _T( "<wx/choicebk.h>" ), GetInfo().ClassName, 0 );
    AddHeader( _T( "<wx/notebook.h>" ), _T( "wxNotebookEvent" ), 0 );
    Codef( _T( "%C(%W, %I, %P, %S, %T, %N);\n" ) );
    BuildSetupWindowCode();
    AddChildrenCode();
    for( int i = 0; i < GetChildCount(); i++ ) {
      wxsChoicebookExtra* CBExtra = ( wxsChoicebookExtra* )GetChildExtra( i );
      Codef( _T( "%AAddPage(%o, %t, %b);\n" ), i, CBExtra->m_Label.wx_str(), CBExtra->m_Selected );
    }
    break;
  }
  case wxsUnknownLanguage:
  default: {
    wxsCodeMarks::Unknown( _T( "wxsChoicebook::OnBuildCreatingCode" ), GetLanguage() );
  }
  }
}

bool wxsChoicebook::OnMouseClick( M_Code_unused wxWindow* Preview, M_Code_unused int PosX, M_Code_unused int PosY ) {
  UpdateCurrentSelection();
  if( GetChildCount() < 2 ) {
    return false;
  }
  int NewIndex = GetChildIndex( m_CurrentSelection ) + 1;
  if( NewIndex >= GetChildCount() ) {
    NewIndex = 0;
  }
  m_CurrentSelection = GetChild( NewIndex );
  GetResourceData()->SelectItem( m_CurrentSelection, true );
  return true;
}

bool wxsChoicebook::OnIsChildPreviewVisible( wxsItem* Child ) {
  UpdateCurrentSelection();
  return Child == m_CurrentSelection;
}

bool wxsChoicebook::OnEnsureChildPreviewVisible( wxsItem* Child ) {
  if( IsChildPreviewVisible( Child ) ) {
    return false;
  }
  m_CurrentSelection = Child;
  UpdateCurrentSelection();
  return true;
}

void wxsChoicebook::UpdateCurrentSelection() {
  wxsItem* NewCurrentSelection = 0;
  for( int i = 0; i < GetChildCount(); i++ ) {
    if( m_CurrentSelection == GetChild( i ) ) {
      return;
    }
    wxsChoicebookExtra* CBExtra = ( wxsChoicebookExtra* )GetChildExtra( i );
    if( ( i == 0 ) || CBExtra->m_Selected ) {
      NewCurrentSelection = GetChild( i );
    }
  }
  m_CurrentSelection = NewCurrentSelection;
}
